package xyz.eden.cloud.common.core.util.ip;

import lombok.extern.slf4j.Slf4j;
import org.lionsoul.ip2region.xdb.Searcher;
import xyz.eden.cloud.common.core.exception.ServiceException;
import xyz.eden.cloud.common.core.util.StringUtils;
import xyz.eden.cloud.common.core.io.file.FileUtils;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Objects;

@Slf4j
public class RegionUtils {

    private static final Searcher SEARCHER;

    private static final String fileName = "ip2region.xdb";

    static {
        // 1. 判断文件是否存在
        File file = FileUtils.getFile(FileUtils.getTempDirectoryPath() + File.separator + fileName);
        if (!file.exists()) {
            InputStream inputStream = RegionUtils.class.getClassLoader().getResourceAsStream(fileName);
            if (Objects.isNull(inputStream)) {
                log.error("[RegionUtils初始化失败] - xdb 文件不存在.");
                throw new ServiceException("xdb 文件不存在.");
            }
            try {
                FileUtils.copyInputStreamToFile(inputStream, file);
            } catch (IOException e) {
                log.error("[RegionUtils初始化失败] - xdb 复制到 temp 目录失败, msg: [{}].", e.getMessage());
                throw new ServiceException("复制 xdb 到 temp 目录失败.");
            }
        }

        // 2. 加载数据到内存种
        byte[] cBuff;
        try {
            cBuff = Searcher.loadContentFromFile(file.getPath());
        } catch (Exception e) {
            log.error("[RegionUtils初始化失败] - 从 xdb 文件加载内容失败, msg: [{}].", e.getMessage());
            throw new ServiceException("从 xdb 文件加载内容失败.");
        }

        // 3. 使用上述的 cBuff 创建一个完全基于内存的查询对象。
        try {
            SEARCHER = Searcher.newWithBuffer(cBuff);
        } catch (Exception e) {
            log.error("[RegionUtils初始化失败] - 读取到 SEARCHER 失败, msg: [{}].", e.getMessage());
            throw new ServiceException("读取到 SEARCHER 失败.");
        }
    }

    public static List<String> getRegionList(String ip) {
        String region = getRegion(ip);
        if (StringUtils.isBlank(region)) {
            return Collections.emptyList();
        }
        return Arrays.asList(region.split("\\|"));
    }

    public static List<String> getRegionList(Long ip) {
        String region = getRegion(ip);
        if (StringUtils.isBlank(region)) {
            return Collections.emptyList();
        }
        return Arrays.asList(region.split("\\|"));
    }

    public static String getRegion(Long ip) {
        if (Objects.isNull(ip)) {
            return "";
        }
        try {
            return SEARCHER.search(ip);
        } catch (Exception e) {
            log.error("[RegionUtils查询失败] - 通过 ip: [{}] 查询出现异常, msg: [{}].", e.getMessage(), e);
            return "";
        }
    }

    public static String getRegion(String ip) {
        if (StringUtils.isBlank(ip)) {
            return "";
        }
        try {
            return SEARCHER.search(ip.trim());
        } catch (Exception e) {
            log.error("[RegionUtils查询失败] - 通过 ip: [{}] 查询出现异常, msg: [{}].", e.getMessage(), e);
            return "";
        }
    }
}
